package com.webex.ta.hydra.gui.wm;

import javax.swing.*;
import java.awt.*;
import java.util.*;

/**
 * Created by Cisco WebEx.
 * User: vegaz
 * Date: 2010-10-19
 * Time: 14:36:20
 */
public class SideBar extends JPanel {
    private static final int DROP_DISTANCE_SENSITIVITY = 20;

    private final ArrayList<SideBarButton> buttons = new ArrayList<SideBarButton>();
    private Dimension prefSize;
    private final int anchor;

    public SideBar(int anchor) {
        this.anchor = anchor;
    }

    public int getAnchor() {
        return anchor;
    }



    @Override
    public void doLayout() {
        recomputeBounds(true, null);
    }

    @Override
    public Dimension getPreferredSize() {
        if (prefSize == null)
            prefSize = recomputeBounds(false, null).size;
        return prefSize;
    }

    private LayoutData recomputeBounds(boolean setBounds, Dimension toFitWidth) {
        return recomputeBounds(setBounds, toFitWidth, true);
    }

    private LayoutData recomputeBounds(boolean setBounds, Dimension toFitWith, boolean noDrop) {
        final LayoutData data = new LayoutData();
        final int horizontaloffset = getHeight();

        data.y = 0;
        data.size = new Dimension();
        data.gap = 1;
        data.horizontal = isHorizontal();
        data.dragInsertPosition = -1;
        if (data.horizontal) {
            data.x = horizontaloffset;
        } else {
            data.x = 0;
        }

        data.fitSize = toFitWith != null ? toFitWith : new Dimension();

        final Rectangle sensitiveRec = new Rectangle(-DROP_DISTANCE_SENSITIVITY, -DROP_DISTANCE_SENSITIVITY,
                getWidth() + DROP_DISTANCE_SENSITIVITY * 2, getHeight() + DROP_DISTANCE_SENSITIVITY * 2);

        // TODO:
        boolean processDrop = false;

        if (toFitWith == null) {
            for (SideBarButton button : buttons) {
                if (!button.isVisible())
                    continue;
                final Dimension size = button.getPreferredSize();
                data.fitSize.width = Math.max(size.width, data.fitSize.width);
                data.fitSize.height = Math.max(size.height, data.fitSize.height);
            }
        }

        int gap = 0;

        if (toFitWith != null) {
            LayoutData layoutData = recomputeBounds(false, null, true);
            if (data.horizontal) {
                gap = toFitWith.width - horizontaloffset - layoutData.size.width - data.x;
            } else {
                gap = toFitWith.height - layoutData.size.height - data.y;
            }

            if (processDrop) {
                //TODO
//                if (data.horizontal) {
//
//                }
            }
        }

        int insertOrder = -1;
        boolean sideStarted = false;

        for (SideBarButton button : getButtonsToLayout()) {
            final Dimension size = button.getPreferredSize();
            if (data.horizontal) {
                data.x += gap;
                data.size.width += gap;
            } else {
                data.y += gap;
                data.size.height += gap;
            }
            layoutButton(data, button, setBounds);
        }


        return data;
    }

    private java.util.List<SideBarButton> getButtonsToLayout() {
        java.util.List<SideBarButton> result = new ArrayList<SideBarButton>();

        for (SideBarButton button : buttons) {
            if (!button.isVisible())
                continue;

            result.add(button);
        }
        return result;
    }

    public boolean isHorizontal() {
        return anchor == SwingConstants.TOP || anchor == SwingConstants.BOTTOM;
    }

    public void addButton(final SideBarButton button) {
        prefSize = null;
        buttons.add(button);
        button.setAnchor(anchor);
        add(button);
        revalidate();
        repaint();
    }

    public void removeButton(final SideBarButton button) {
        prefSize= null;
        buttons.remove(button);
        remove(button);
        revalidate();
        repaint();
    }

    private static void layoutButton(final LayoutData data, final JComponent button, boolean setBounds) {
        final Dimension size = button.getPreferredSize();
        if (setBounds) {
            final int width = data.horizontal ? size.width : data.fitSize.width;
            final int height = data.horizontal ? data.fitSize.height : size.height;
            button.setBounds(data.x, data.y, width, height);
        }

        if (data.horizontal) {
            final int deltaX = size.width + data.gap;
            data.x += deltaX;
            data.size.width += deltaX;
            data.size.height = size.height;
        } else {
            final int deltaY = size.height + data.gap;
            data.y += deltaY;
            data.size.width = size.width;
            data.size.height += deltaY;
        }
    }


    private static class LayoutData {
        int x, y;
        int gap;
        Dimension size;
        Dimension fitSize;
        boolean horizontal;
        int processedComponents;

        boolean dragTargetChosen;
        boolean dragToSide;
        int dragInsertPosition;
    }
}
